﻿using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using umbraco;
using umbraco.BasePages;
using umbraco.BusinessLogic;
using umbraco.interfaces;
using umbraco.controls;
using umbraco.uicontrols;
using umbraco.cms.businesslogic.member;
using Commerce.Common;
using System.Net.Mail;

namespace CommerceForUmbraco.adminSection.commerce
{
    public partial class editOrder : umbraco.BasePages.UmbracoEnsuredPage
    {
        #region properties

        public TabPage MainTab;
        public TabPage ItemTab;
        public TabPage NoteTab;
        public TabPage TransTab;
        public TabPage EditTab;

        // TODO: Gary
        //private umbraco.controls.datePicker OrderDate;

        protected decimal orderSubTotal = 0;
        protected string productsArrayStr = "{}";

        // order
        private Order thisOrder;

        #endregion

        protected void Page_Load(object sender, EventArgs e)
        {
            string orderId = Request.QueryString.Get("o");
            thisOrder = OrderController.GetOrder(int.Parse(orderId));
            bool isPO = false;
            if (!IsPostBack)
            {
                orderNumber.Text = thisOrder.OrderNumber;
                TextBoxOrderDate.Text = thisOrder.OrderDate.ToLongDateString();
                if (string.IsNullOrEmpty(thisOrder.PoNumber) == false)
                {
                    isPO = true;
                    LabelPO.Visible = true;
                    CheckBoxPaymentReceived.Visible = true;
                    LabelPO.Text = thisOrder.PoNumber;
                    CheckBoxPaymentReceived.Checked = thisOrder.ReceivedPayment.Value;
                }
                else
                {
                    LabelPO.Visible = false;
                    CheckBoxPaymentReceived.Visible = false;
                }
                orderStatusDisplay.Text = thisOrder.OrderStatus.ToString();

                billTo.Text = thisOrder.BillToAddress;
                shipTo.Text = thisOrder.ShipToAddress;

                //////////////////////
                // ROB: safer way to get current and legacy members...fixes crash bug.  9/9/2010
                Member[] thisMember = Member.GetMemberByName(thisOrder.UserName, false);
                int memberId = -1;
                string business = "";
                if (thisMember.Length > 0)
                {
                    memberId = thisMember[0].Id;
                    
                    if (thisMember[0].getProperty("businessName") != null)
                    {
                        business = thisMember[0].getProperty("businessName").Value.ToString();
                    }
                }
                //////////////////////

                ///int memberId = Member.GetMemberFromEmail(thisOrder.Email).Id;
                memberLink.Text = String.Format("<a href='/umbraco/members/EditMember.aspx?id={1}' target='_blank'>{0}</a>", thisOrder.Email, memberId);
                ///string business = Member.GetMemberFromEmail(thisOrder.Email).getProperty("businessName").Value.ToString();
                //businessName.Text = business;
                emailAddress.Text = thisOrder.Email;
                CouponCodes.Text = thisOrder.CouponCodes;

                ShippingTypesCollection shipTypes = new ShippingTypesCollection().Load();
                shippingMethod.Items.Clear();
                foreach (ShippingTypes thisType in shipTypes)
                {
                    shippingMethod.Items.Add(new ListItem(thisType.ShippingType, thisType.ShippingTypeID.ToString()));
                }
                shippingMethod.SelectedIndex = shippingMethod.Items.IndexOf(shippingMethod.Items.FindByText(thisOrder.ShippingMethod));

                shippingMethodActual.Text = thisOrder.ShippingMethod;

                TrackingNumber.Text = thisOrder.ShippingTrackingNumber;

                // Items tab
                OrderItems.Text = thisOrder.ItemsToString(true);

                // Notes tab ( a little Edit Order Status thrown in )
                OrderStatussCollection orderStatuses = new OrderStatussCollection().Load();
                orderStatusDDL.Items.Clear();
                editOrderStatusDDL.Items.Clear();
                foreach (OrderStatuss thisStatus in orderStatuses)
                {
                    orderStatusDDL.Items.Add(new ListItem(thisStatus.OrderStatussX, thisStatus.OrderStatussID.ToString()));
                    editOrderStatusDDL.Items.Add(new ListItem(thisStatus.OrderStatussX, thisStatus.OrderStatussID.ToString()));
                }
                orderStatusDDL.SelectedIndex = orderStatusDDL.Items.IndexOf(orderStatusDDL.Items.FindByValue(thisOrder.OrderStatusID.ToString()));
                editOrderStatusDDL.SelectedIndex = orderStatusDDL.Items.IndexOf(orderStatusDDL.Items.FindByValue("15"));    // Edited Order

                gNotes.DataSource = thisOrder.Notes;
                gNotes.DataBind();

                // Transactions tab
                gTransactions.DataSource = thisOrder.Transactions;
                gTransactions.DataBind();

                TransactionTypesCollection transTypes = new TransactionTypesCollection().Load();
                addTransactionType.Items.Clear();
                foreach (TransactionTypes thisType in transTypes)
                {
                    addTransactionType.Items.Add(new ListItem(thisType.TransactionType, thisType.TransactionTypeID.ToString()));
                }
                addTransactionType.SelectedIndex = addTransactionType.Items.IndexOf(addTransactionType.Items.FindByValue("5"));

                // Edit Order tab
                rptBasket.DataSource = thisOrder.Items;
                rptBasket.DataBind();

                string arrayProds = LoadProductsForAutoComplete();
                //this.autocompleteArray.Controls.Add(new LiteralControl(String.Format("<div>{0}</div>", this.productsArrayStr)));
                this.autocompleteArray.Controls.Add(new LiteralControl(String.Format("<script type=\"text/javascript\">var products = [{0}];</script>", arrayProds)));
                
                // Special Instruction - Gift
                OrderInstructionCollection instr = new OrderInstructionCollection().Where("orderId", SubSonic.Comparison.Equals, orderId).Load();
                if( instr.Count > 0 )
                {
                    isGift.Checked = instr[0].IsGift;
                    instructionNote.Text = instr[0].Note;
                }
            }

            // Main tab
            this.Pane1.Text = "Order Details";
            this.pp_ordernumber.Text = "Order Number";
            this.pp_orderdate.Text = "Order Date";
            if (isPO == true)
            {
                this.pp_orderPO.Text = "Purchase Order #";
                this.pp_paymentReceived.Text = "Payment Received";
            }
            this.pp_orderStatus.Text = "Order Status";
            this.pp_billto.Text = "Bill To";
            this.pp_shipto.Text = "Ship To";
            this.pp_email.Text = "Email";
            //this.pp_businessName.Text = "Business Name";
            this.pp_memberlink.Text = "View User";
            this.pp_coupon.Text = "Coupon Used";
            this.pp_shipping_method.Text = "Shipping Method";
            this.pp_shipping_method_actual.Text = "Selected Shipping Method";
            this.pp_tracking.Text = "Tracking Number";
            this.pp_cancel.Text = "Cancel Order?";
            this.pp_IsGift.Text = "No Receipt with Order";
            this.pp_GiftMessage.Text = "Special Message";

            // Items tab
            this.Pane2.Text = "Order Items";
            this.pp_order_items.Text = "Order Items";

            // Notes tab
            this.Pane3.Text = "Order Notes";
            this.pp_notes.Text = "Order Note";
            this.pp_notestatus.Text = "Order Status";
            this.pp_notelist.Text = "Note History";

            // Transactions tab
            this.Pane4.Text = "Transactions";
            this.pp_transactions.Text = "Order Transactions";
            this.pp_transactions_add.Text = "Add Manual Transaction";
            this.pp_transactions_addnote.Text = "Note";

             // Edit Order tab
            this.Pane5.Text = "Add/Remove/Update Order Items";
            this.pp_editorder_notestatus.Text = "Order Status";
            this.pp_editorder_notes.Text = "Order Note";
            this.pp_editorder_items.Text = "Change Quantity or Remove";
            this.pp_editorder_newitem.Text = "Add New Product";
            //this.pp_editorder_newitem.Visible = false;      // JASON: No way to add product options so its removed for now.

        }

        protected override void OnInit(EventArgs e)
        {

            // Tab setup
            MainTab = tabControl.NewTabPage("Main");
            MainTab.Controls.Add(Pane1);

            ItemTab = tabControl.NewTabPage("Items");
            ItemTab.Controls.Add(Pane2);

            NoteTab = tabControl.NewTabPage("Notes");
            NoteTab.Controls.Add(Pane3);

            TransTab = tabControl.NewTabPage("Transactions");
            TransTab.Controls.Add(Pane4);

            EditTab = tabControl.NewTabPage("Edit Order Items");
            EditTab.Controls.Add(Pane5);

            // Gary
            //Add date control
            //OrderDate = new datePicker();
            //OrderDate.ID = "orderdate";
            //OrderDate.ShowTime = true;

            //pnlOrderDate.Controls.Add(OrderDate);

            // Main Tab
            ImageButton save = MainTab.Menu.NewImageButton();
            save.Click += new ImageClickEventHandler(this.save_click);
            save.AlternateText = "Save";
            save.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";

            ImageButton print = MainTab.Menu.NewImageButton();
            print.AlternateText = "Print";
            print.OnClientClick = String.Format("printWindow({0})", Request.QueryString.Get("o"));
            print.ImageUrl = GlobalSettings.Path + "/images/editor/print.png";

            // Item Tab
            ImageButton save2 = ItemTab.Menu.NewImageButton();
            save2.Click += new ImageClickEventHandler(this.save_click);
            save2.AlternateText = "Save";
            save2.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";

            ImageButton print2 = ItemTab.Menu.NewImageButton();
            print2.AlternateText = "Print";
            print2.OnClientClick = String.Format("printWindow({0})", Request.QueryString.Get("o"));
            print2.ImageUrl = GlobalSettings.Path + "/images/editor/print.png";

            // Note Tab
            ImageButton save3 = NoteTab.Menu.NewImageButton();
            save3.Click += new ImageClickEventHandler(this.save_click);
            save3.AlternateText = "Save";
            save3.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";

            ImageButton print3 = NoteTab.Menu.NewImageButton();
            print3.AlternateText = "Print";
            print3.OnClientClick = String.Format("printWindow({0})", Request.QueryString.Get("o"));
            print3.ImageUrl = GlobalSettings.Path + "/images/editor/print.png";

            // Trans Tab
            ImageButton save4 = TransTab.Menu.NewImageButton();
            save4.Click += new ImageClickEventHandler(this.save_click);
            save4.AlternateText = "Save";
            save4.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";

            ImageButton print4 = TransTab.Menu.NewImageButton();
            print4.AlternateText = "Print";
            print4.OnClientClick = String.Format("printWindow({0})", Request.QueryString.Get("o"));
            print4.ImageUrl = GlobalSettings.Path + "/images/editor/print.png";

            // Edit Tab
            ImageButton save5 = EditTab.Menu.NewImageButton();
            save5.Click += new ImageClickEventHandler(this.save_click);
            save5.AlternateText = "Save";
            save5.ImageUrl = GlobalSettings.Path + "/images/editor/save.gif";

            ImageButton print5 = EditTab.Menu.NewImageButton();
            print5.AlternateText = "Print";
            print5.OnClientClick = String.Format("printWindow({0})", Request.QueryString.Get("o"));
            print5.ImageUrl = GlobalSettings.Path + "/images/editor/print.png";


            base.Load += new EventHandler(this.Page_Load);
            this.InitializeComponent();
            base.OnInit(e);
        }

        private void InitializeComponent()
        {
        }

        private bool SaveOrder(string orderId)
        {
            Order thisOrder = new Order(int.Parse(orderId));

            try
            {
                // Gary
                thisOrder.OrderDate = System.DateTime.Parse(TextBoxOrderDate.Text);
                thisOrder.ShippingMethod = shippingMethod.SelectedItem.Text;
                thisOrder.ReceivedPayment = CheckBoxPaymentReceived.Checked;

                thisOrder.Save("Commerce For Umbraco");

                return true;

            }
            catch 
            {
                return false;                
            }
        }

        private string LoadProductsForAutoComplete()
        {
            ProductCollection products = ProductController.GetAll();

            var sb = new System.Text.StringBuilder();

            string comma = "";
            foreach (var prod in products)
            {
                if (prod.Status != ProductStatus.Inactive)
                {
                    sb.AppendFormat("{1}\"{0}\"", prod.ProductName.Replace("\"","&quot;"), comma);
                    //sb.AppendFormat("{{ name: \"{0}\", id: \"{1}\" }}", prod.ProductName, prod.ProductID);
                    comma = ", ";
                }
            }

            productsArrayStr = sb.ToString();

            return sb.ToString();
        }
        
        #region button handlers

        private void save_click(object sender, ImageClickEventArgs e)
        {
            if (this.SaveOrder(base.Request.QueryString["o"]))
            {
                base.ClientTools.ShowSpeechBubble(0, ui.Text("speechBubbles", "commerceItemSaved"), "");
            }
            else
            {
                base.ClientTools.ShowSpeechBubble(0, ui.Text("speechBubbles", "commerceItemErrorHeader"), ui.Text("speechBubbles", "commerceItemErrorText"));
            }
        }

        protected void shipButton_Click(object sender, EventArgs e)
        {
            thisOrder.OrderStatus = OrderStatus.ShippedToCustomer;
            thisOrder.ShippingTrackingNumber = TrackingNumber.Text.Trim();
            thisOrder.Save("Commerce For Umbraco");

            // add a note
            OrderNote note = new OrderNote();
            note.OrderID = thisOrder.OrderID;
            note.OrderStatus = OrderStatus.ShippedToCustomer.ToString();
            note.Note = String.Format("Tracking number: {0}",TrackingNumber.Text.Trim());
            note.Save("Commerce For Umbraco");

            if (MessagingController.SendOrderShippedEmail(thisOrder))
            {
                base.ClientTools.ShowSpeechBubble(0, ui.Text("speechBubbles", "Shipped Email Sent"), "");
            }
            else
            {
                base.ClientTools.ShowSpeechBubble(0, ui.Text("speechBubbles", "Error"), ui.Text("speechBubbles", "Shipped notification could not be sent"));
            }

            // refresh thisOrder object
            thisOrder = OrderController.GetOrder(thisOrder.OrderID);

            orderStatusDisplay.Text = thisOrder.OrderStatus.ToString();

            gNotes.DataSource = thisOrder.Notes;
            gNotes.DataBind();
        }

        protected void cancelButton_Click(object sender, EventArgs e)
        {
            thisOrder.OrderStatus = OrderStatus.OrderCancelledPriorToShipping;
            thisOrder.Save("Commerce For Umbraco");
            
            // add a note
            OrderNote note = new OrderNote();
            note.OrderID = thisOrder.OrderID;
            note.OrderStatus = OrderStatus.OrderCancelledPriorToShipping.ToString();
            note.Note = cancelNote.Text;
            note.Save("Commerce For Umbraco");

            if (MessagingController.SendOrderCancelledEmail(thisOrder))
            {
                base.ClientTools.ShowSpeechBubble(0, ui.Text("speechBubbles", "Cancellation Email Sent"), "");
            }
            else
            {
                base.ClientTools.ShowSpeechBubble(0, ui.Text("speechBubbles", "Error"), ui.Text("speechBubbles", "Cancellation notification could not be sent"));
            }
            
            // refresh thisOrder object
            thisOrder = OrderController.GetOrder(thisOrder.OrderID);

            orderStatusDisplay.Text = thisOrder.OrderStatus.ToString();

            gNotes.DataSource = thisOrder.Notes;
            gNotes.DataBind();
        }

        protected void AddNoteButton_Click(object sender, EventArgs e)
        {
            //JASON: update the order status as well.
            thisOrder.OrderStatus = ((OrderStatus)Int32.Parse(orderStatusDDL.SelectedItem.Value));
            thisOrder.Save(User.Identity.Name);

            AddOrderNote(orderStatusDDL.SelectedItem.Text, OrderNote.Text, "");

            //JASON: re-bind the order status
            orderStatusDisplay.Text = thisOrder.OrderStatus.ToString();

            OrderNote.Text = string.Empty;
        }

        private void AddOrderNote( string orderStatusText, string noteText, string additionalText )
        {
            OrderNote note = new OrderNote();
            note.OrderID = thisOrder.OrderID;
            note.OrderStatus = orderStatusText;
            note.Note = String.Format("{0} -- {1}", noteText, additionalText);
            note.Save(User.Identity.Name);

            // refresh thisOrder object
            thisOrder = OrderController.GetOrder(thisOrder.OrderID);

            gNotes.DataSource = thisOrder.Notes;
            gNotes.DataBind();
        }


        public void R1_ItemCommand(Object sender, RepeaterCommandEventArgs e)
        {
            if (editOrderStatusNote.Text.Length > 0)
            {
                string action = ((ImageButton)e.CommandSource).CommandArgument;

                switch (action)
                {
                    case "remove":
                        //DeleteItem(sender, e);
                        break;
                    case "update":
                        UpdateItem(sender, e);
                        break;
                }
            }
            else
            {
                base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Edit Error", "You must add a note before editing this order");
            }
        }

        protected void UpdateItem(Object sender, RepeaterCommandEventArgs e)
        {
            Label lblProductID = (Label)e.Item.FindControl("lblProductID");
            Label lblSKU = (Label)e.Item.FindControl("lblSKU");
            Label lblAttributes = (Label)e.Item.FindControl("lblAttributes");
            TextBox newQuantity = (TextBox)e.Item.FindControl("qtyEntry");
            int orderID = thisOrder.OrderID;

            var sb = new System.Text.StringBuilder();

            if (lblProductID != null && lblSKU != null && newQuantity != null)
            {
                Int32 prodid = int.Parse(lblProductID.Text);
                Int32 quantity = int.Parse(lblProductID.Text);
                bool prodOK = Int32.TryParse(lblProductID.Text, out prodid);
                bool qtyOK = Int32.TryParse(newQuantity.Text, out quantity);

                if (prodOK && qtyOK)
                {
                    OrderController.AdjustQuantity(orderID, prodid, lblAttributes.Text, quantity);

                    Product prod = ProductController.GetProduct(prodid);
                    sb.AppendFormat("Updated product \"{0}\" to a new quantity of: {1}", prod.ProductName, newQuantity.Text);
                }
                else
                {
                    base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Edit Error", "Please enter a valid number for the quantity.");
                }
            }

            AddOrderNote(editOrderStatusDDL.SelectedItem.Text, editOrderStatusNote.Text, sb.ToString());
            editOrderStatusNote.Text = string.Empty;

            OrderItems.Text = thisOrder.ItemsToString(true);
        }

        protected void editOrder_AddButton_Click(object sender, EventArgs e)
        {
            if (editOrderStatusNote.Text.Length > 0)
            {
                System.Data.IDataReader rdr = Commerce.Common.Product.FetchByParameter(Commerce.Common.Product.Columns.ProductName, editOrder_AddProduct.Text);
                rdr.Read();

                Commerce.Common.Product prod = new Product();
                prod.Load(rdr);

                rdr.Close();

                if (prod != null)
                {
                    if (prod.ProductName.Length > 0)
                    {
                        prod.Quantity = 1;
                        OrderController.AddItemToOrder(thisOrder.OrderID, prod);

                        var sb = new System.Text.StringBuilder();
                        sb.AppendFormat("Added product \"{0}\"", prod.ProductName);

                        AddOrderNote(editOrderStatusDDL.SelectedItem.Text, editOrderStatusNote.Text, sb.ToString());
                        editOrderStatusNote.Text = string.Empty;

                        OrderItems.Text = thisOrder.ItemsToString(true);
                        rptBasket.DataSource = thisOrder.Items;
                        rptBasket.DataBind();
                    }
                    else
                    {
                        base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Add Error", "Product not found or is incorrect");
                    }
                }
                else
                {
                    base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Add Error", "Product not found");
                }
            }
            else
            {
                base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Add Error", "You must add a note before editing this order");
            }
        }

        protected void addTransactionButton_Click(object sender, EventArgs e)
        {
            if (addTransactionNote.Text.Length > 0)
            {
                if (addTransactionAmount.Text.Length > 0)
                {
                    decimal amount;
                    if (decimal.TryParse(addTransactionAmount.Text, out amount))
                    {
                        TransactionController tc = new TransactionController();

                        tc.Insert(thisOrder.OrderID, "", DateTime.Now, 5, amount, addTransactionNote.Text, DateTime.UtcNow, User.Identity.Name, DateTime.UtcNow, User.Identity.Name);


                        gTransactions.DataSource = thisOrder.TransactionRecords();
                        gTransactions.DataBind();

                        System.Text.StringBuilder sb = new System.Text.StringBuilder();
                        if (amount > 0)
                        {
                            sb.AppendFormat("Charged ${0:##.00} to order", amount);
                        }
                        else
                        {
                            sb.AppendFormat("Credited ${0:##.00} to order", amount);
                        }

                        AddOrderNote(editOrderStatusDDL.SelectedItem.Text, addTransactionNote.Text, sb.ToString());
                    }
                    else
                    {
                        base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Add Error", "Please enter a valid amount in the format (000.00)");
                    }
                }
                else
                {
                    base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Add Error", "Please enter an amount");
                }
            }
            else
            {
                base.ClientTools.ShowSpeechBubble(speechBubbleIcon.error, "Add Error", "You must add a note before adding a transaction");
            }
        }

        //protected void DeleteItem(Object sender, RepeaterCommandEventArgs e)
        //{
        //    Label lblProductID = (Label)e.Item.FindControl("lblProductID");

        //    var sb = new System.Text.StringBuilder();

        //    if (lblProductID != null)
        //    {
        //        OrderController.RemoveItem(int.Parse(lblProductID.Text));

        //        Product prod = ProductController.GetProduct(int.Parse(lblProductID.Text));
        //        sb.AppendFormat("Deleted product \"{0}\" from the order.", prod.ProductName);
        //    }

        //    AddEditOrderNote(sb.ToString());

        //    OrderItems.Text = thisOrder.ItemsToString(true);
        //}

        #endregion


    }
}
